package cn.snmp.mutual.handler;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedList;

import cn.snmp.mutual.constants.NnTempLetError;
import cn.snmp.mutual.nms.ErrorMessages;
import cn.snmp.mutual.nms.SnmpVar;
import cn.snmp.mutual.nms.SnmpVarBind;
import lombok.extern.slf4j.Slf4j;

import cn.snmp.mutual.data.ObjService;
import cn.snmp.mutual.common.snmp.SnmpNioTarget;
import cn.snmp.mutual.util.OperatorUtilities;
import cn.snmp.mutual.util.Utilities;

/**
 * @author dengkn
 * 获取一行数据
 */
@Slf4j
public class SnmpGetTableRow {



    /**
     * @param snmpTarget : SnmpTarget 实例
     * @param osParams   : 在配置文件中定义的表信息
     * @param osResult   : result 返回结果实例
     */
    public static void hander(SnmpNioTarget snmpTarget, ObjService osParams, ObjService osResult) {
        try {
            snmpTarget.setSNMPOpType(SnmpNioTarget.SNMP_GET_TABLE_ROW);
            String strInstance = osParams.getStringValue("Instance");
            LinkedList<ObjService> vIndexNodes = new LinkedList<ObjService>();
            LinkedList<ObjService> vAccessNodes = new LinkedList<ObjService>();
            int iNodeCount = osResult.objectSize("MibNode");
            for (int i = 0; i < iNodeCount; i++) {
                ObjService osNode = osResult.objectAt("MibNode", i);
                String strOID = osNode.getStringValue("OID");
                if (strOID.equals("")) {
                    continue;
                }
                String access = osNode.getStringValue("Access");
                if (Utilities.isIndexNode(osNode)) {
                    vIndexNodes.add(osNode);
                }
                if (!access.equalsIgnoreCase("noaccess")) {
                    vAccessNodes.add(osNode);
                }
            }
            if (vAccessNodes.size() == 0) {
                log.info("mutual get table row handler error,acessnode = 0");
                snmpTarget.setFinishTag(true);
                osResult.setValue("ErrCode", "" + NnTempLetError.SNMP_NODE_NOT_FOUND);
                osResult.setValue("isFinish", "true");
                osResult.setValue("ErrDesc", "SNMP_NODE_NOT_FOUND");
                return;
            }
            ObjService osAccessNodeOIDTable = new ObjService();
            ObjService osNodeNameTable = new ObjService();
            LinkedList<String> vAccessNodeOIDs = new LinkedList<String>();
            for (int i = 0; i < vAccessNodes.size(); i++) {
                ObjService osNode = (ObjService) vAccessNodes.get(i);
                String strOID = osNode.getStringValue("OID") + "." + strInstance;
                String strLogic = osNode.getStringValue("Logic");
                osNodeNameTable.setValue(strLogic, strOID);
                String strIsExists = osAccessNodeOIDTable.getStringValue(strOID);
                if (!strIsExists.equalsIgnoreCase("true")) {
                    osAccessNodeOIDTable.setValue(strOID, "true");
                    vAccessNodeOIDs.add(strOID);
                }
            }
            osResult.setValue("isFinish", "true");
            String[] strOIDs = new String[vAccessNodeOIDs.size()];
            for (int i = 0; i < vAccessNodeOIDs.size(); i++) {
                strOIDs[i] = vAccessNodeOIDs.get(i);
            }
            snmpTarget.setObjectIDList(strOIDs);
            if ((strOIDs == null) || (strOIDs.length < 1)) {
                snmpTarget.setFinishTag(true);
                snmpTarget.setErrCode(21);
                snmpTarget.setErrDes(ErrorMessages.getErrorString(21));
                return;
            }
            snmpTarget.setSTRowParam(vIndexNodes, vAccessNodes);
        } catch (Exception e) {
            log.error("mutual get table row handler error,Exception = ", e);
            osResult.setValue("ErrCode", "801");
            osResult.setValue("ErrDesc", e.getMessage());
            snmpTarget.setFinishTag(true);
        }
    }

    /**
     * @param target : SnmpNioTarget 实例
     * @return : 最终结果
     */

    public static void parser(SnmpNioTarget target) {
        try {
            ObjService osCommandParams = target.getOsParam();
            String strInstance = osCommandParams.getStringValue("Instance");
            String sns = osCommandParams.getStringValue("InstanceS");
            String[] sss = sns.split(",");
            if (sss.length > 1) {
                LinkedList<String> vecs = new LinkedList<String>();
                for (int i = 0; i < sss.length; i++) {
                    vecs.add(sss[i]);
                }
                for (int i = 0; i < vecs.size(); i++) {
                    parser(target, vecs.get(i), true);
                }

            } else if (osCommandParams.objectSize("Instance") > 0) {
                ObjService osInstances = osCommandParams.objectAt("Instance", 0);
                LinkedList<String> vInstances = OperatorUtilities.shortInstance(osInstances);
                for (int i = 0; i < vInstances.size(); i++) {
                    parser(target, vInstances.get(i), true);
                }
            } else if (!strInstance.equals("")) {
                parser(target, strInstance, false);
            }
        } catch (Exception e) {
            log.error("mutual get table row handler error,Exception = ", e);
            target.getResult().setValue("ErrCode", "801");
            target.getResult().setValue("ErrDesc", e.getMessage());
        }
    }

    private static void parser(SnmpNioTarget target, String strInstance, boolean ignore) {
        ArrayList<SnmpVarBind> orgResult = (ArrayList<SnmpVarBind>) target.getOrgResult();
        ObjService result = target.getResult();
        result.setValue("isFinish", "true");
        if (!ignore) {
            if (orgResult.size() != target.getOidList().length) {
                result.setValue("ErrCode", "" + NnTempLetError.AGENT_REPONSE_ERROR);
                result.setValue("ErrDesc", NnTempLetError.getErrorMessage(NnTempLetError.AGENT_REPONSE_ERROR));
                return;
            }
        }
        if (orgResult.size() == 0) {
            result.setValue("ErrCode", "2");
            result.setValue("ErrDesc", "Table Row is null");
            return;
        }

        LinkedList<ObjService> vIndexNodes = target.getTRIndexNodes();
        LinkedList<ObjService> vAccessNodes = target.getTRAccessNodes();
        ObjService osRowSet = new ObjService("RowSet");

        try {
            OperatorUtilities.calculateTableIndexsValue(vIndexNodes, strInstance, osRowSet, target.getOsParam());
        } catch (Exception e1) {
            e1.printStackTrace();
            result.setValue("ErrCode", "2");
            result.setValue("ErrDesc", "Table Row is null");
            return;
        }
        Hashtable htBindTable = new Hashtable();
        for (int i = 0; i < orgResult.size(); i++) {
            SnmpVarBind tvb = orgResult.get(i);
            htBindTable.put(tvb.getObjectID().toString(), tvb.getVariable());
        }

        for (int i = 0; i < vAccessNodes.size(); i++) {
            try {
                ObjService mibNode = (ObjService) vAccessNodes.get(i);
                String logicName = mibNode.getStringValue("Logic");
                String strOID = mibNode.getStringValue("OID");
                strOID = strOID + "." + strInstance;
                SnmpVar var = (SnmpVar) htBindTable.get(strOID);
                Object value = OperatorUtilities.readSnmpVar(var, mibNode, target.getOsParam(), osRowSet);
                osRowSet.setValue(logicName, value);

            } catch (Exception e) {
                log.error("mutual get table row parser error,Exception = ", e);
                result.setValue("ErrCode", "" + NnTempLetError.MIBNODEADAPTER_READ_ERROR);
                result.setValue("ErrDesc", e.toString());
                return;
            }
        }
        osRowSet.setValue("Instance", strInstance);
        result.addContainedObject(osRowSet);
        result.setValue("ErrCode", "0");
        result.setValue("ErrDesc", "Get Table Row Success");
    }
}
